<?php
namespace Admin\Service;

use \Admin\Model;

class EcontractService {
    const API_ADD = 'add';//录入接口
    const API_READ = 'read';//单个合同状态查询接口
    const API_BATCH_READ = 'batchRead';//合同批量查询接口
    const API_TOKEN = 'token';//API接口调用增加 TOKEN验证
    const API_SURVEY_READ = 'survey/read'; //问卷读取接口

    const CACHE_TOKEN_KEY = 'token'; //token 缓存文件名
    const ERR_POST_SUCCESS = 1000;
    const COMPNAY_ID_CRM = 1;

    const TM_TOKEN_EXPIRE = 7000;// TOKEN 过期时间
 
    protected $m_api_base = '';

    public function __construct()
    {
        $config = C('ECONTRACT');
        $this->m_api_base = $config&&$config['API_BASE'] ? $config['API_BASE']:'';
    }

    //
    /**
     * 推送电子合同
     * 
     * @param  int     contract_id  合同ID 
     * @param  string  callback     合同回调地址
     * 
     * @return array('rcode'=>'返回代码,1:成功；0：失败','data'=>'返回数据','msg'=>'提示消息')
     */
    public function post( $contract_id , $callback = '' )
    {
        $res  = array('rcode'=>0,'msg'=>'参数错误', 'data'=>NULL);
        $Mdo = D('Admin/Contract');
        $where = array();
        $where['c.contract_id'] = array('eq', $contract_id);
        $data = $Mdo->alias("c")
                    ->field("c.*,p.name as product_name")
                    ->join("LEFT JOIN product p on p.product_id=c.product_id")
                    ->where( $where )
                    ->find();

        if (!$data || $data['is_delete'] ==1 ) {
            $res['msg'] = "无效合同数据";
        }
        else {
            if ($data['merge_to'] || !(intval($data['state']) == \Admin\Model\ContractModel::STATE_NEED_AUTH || 
                                ($data['state']==\Admin\Model\ContractModel::STATE_SIGNING) ) ) {
                $res['msg'] = "合同不能再次签订合同";
            }
            else {
                #TODO 增加合同系统订单状态判断
                $apiParam  = array();
                $apiParam['timestamp'] = date('YmdHis');
                $apiParam['customer_id_crm'] =  $data['customer_id'];
                $apiParam['name'] = $data['second_party_name'];
                $apiParam['id_number'] = $data['second_party_idcard'];
                $apiParam['phone_number'] = $data['second_party_phone'];
                $apiParam['address'] = $data['second_party_address'];
                if ($apiParam['second_party_email'])
                    $apiParam['email'] = $data['second_party_email'];
                $apiParam['contract_number'] = $data['order_num']; // 合同编号
                $apiParam['templet_contract_id'] = 1;
                $apiParam['templet_contract_url'] = '';
                $apiParam['contract_title'] = $data['order_num'];;
                $apiParam['product_name'] = $data['product_name'];
                $apiParam['price'] = $data['mount'];
                $apiParam['start_time'] = $data['start_time'];
                $apiParam['end_time'] = $data['end_time'];
                $apiParam['company_id_crm'] = self::COMPNAY_ID_CRM;
                $apiParam['company_name'] = $data['first_party_name'];
                //增加合同回调地址参数
                if ($callback)
                    $apiParam['callback'] = $callback;

                //增加风险问卷信息
                $apiParam['survey_code'] = $data['survey_code'];
                //$apiParam['company_address'] = $data['first_party_address'];
                //$apiParam['company_account'] = $data['first_party_bank_account'];
                //$apiParam['company_bank'] = $data['first_party_bank_deposit'];
                //$apiParam['company_telephone'] = '';

                //参数提前验证
                if (!(isset($apiParam['customer_id_crm']) && isset($apiParam['name']) && isset($apiParam['phone_number'])) ){
                    $res['msg'] = "客户信息参数缺失或不合法";
                    return $res;
                }
                //风险问卷验证
                if (!isset($apiParam['survey_code']) || !$apiParam['survey_code']){
                    $res['msg'] = '问卷编号不能为空';
                    return $res;
                }
                /**
                * 电子合同路录入接口新增自定义参数字段
                * 字段名: extend
                * 参数规则：　json 字符串
                * 增加一次签订合同信息
                */
                $extendData = array();
                $extendData['company_address'] =  $data['first_party_address'];
                $extendData['company_account'] = $data['first_party_bank_account'];
                $extendData['company_bank'] = $data['first_party_bank_deposit'];
                $extendData['company_name'] = $data['first_party_name'];
                $extendData['teacher_name'] = $data['teacher_name'];
                $extendData['teacher_cert']  = $data['teacher_cert'];
                

                //公司信息不能为空
                if (!$extendData['company_account'] || !$extendData['company_address'] || !$extendData['company_bank']){
                    $res['msg'] = '合同中公司信息必须完整';
                    return $res;
                }
                //投顾老师不能为空
                if (!$extendData['teacher_name'] || !$extendData['teacher_cert']){
                    $res['msg'] = '投顾老师的姓名与证书编号不能为空,请检查产品绑定的老师';
                    return $res;
                }
                //判断用户是否签订过合同
                $wherec = array();
                $wherec['c.customer_id'] = array('eq', $data['customer_id']);
                $wherec['c.end_time'] = array('gt', date('Y-m-d 0:0:0'));
                $wehrec['c.state'] = array('eq', \Admin\Model\ContractModel::STATE_SERVICE);
                $lastContract = $Mdo->alias("c")
                                    ->field("c.*,p.name as product_name")
                                    ->join("LEFT JOIN product p on p.product_id=c.product_id")
                                    ->where( $wherec )
                                    ->order("c.create_time desc")
                                    ->find();

                //以前续费合同需要单独签订个一个作废申明、电子合同暂时不处理
                if ($lastContract&&0) {
                    /**
                    *合同条款中续费的问题  4.2中合同　咨询费用为两个合同之和
                    *  4.5中的金额为本次合同的金额
                    */
                    $apiParam['price'] = doubleval($data['mount']) + doubleval($lastContract['mount']);
                    $extendData['last_sign_time'] = $lastContract['start_time']; //上一份合同签订时间
                    $tm = strtotime($lastContract['start_time']);
                    $extendData['last_sign_year'] = date('Y', $tm);
                    $extendData['last_sign_month'] = date('m', $tm);
                    $extendData['last_sign_day'] = date('d', $tm);
                    $extendData['last_contract_order'] = $lastContract['order_num']; //上一次合同编号
                    $extendData['last_buy_product'] = $lastContract['product_name']; //上一次购买产品
                    $extendData['shengji_product'] = $data['product_name'];
                    $extendData['shengji_price'] = $data['mount']; //升级付款金额
                    $extendData['shengji_price_cn'] = num_to_rmb($data['mount']);//升级金额大写
                }

                $apiParam['extend'] = json_encode( $extendData );
                $token = $this->_token();
                $ret = $this->_httpPost($this->m_api_base.self::API_ADD.'?token='.$token, $apiParam);
                $jsonRet = $ret&&json_decode($ret) ? json_decode($ret, true) : false;
                if (!$ret) {
                    $res['msg'] = "接口访问失败";
                }
                else if ($ret&&$jsonRet['code']==self::ERR_POST_SUCCESS) {
                    $res['msg'] = '合同信息录入成功';
                    $res['data'] = $jsonRet;
                    $res['rcode'] = 1;
                    
                    //合同录入成交，更新合同状态
                    $where = array();
                    $where['c.contract_id'] = array('eq', $contract_id);
                    $dup = array();
                    $dup['state'] = \Admin\Model\ContractModel::STATE_SIGNING;
                    $dup['type'] = 2;//合同类型修改成电子合同
                    $Mdo->alias("c")->where( $where )->save( $dup );
                }
                else {
					$this->_clearTokenByCode( $jsonRet, $token);
                    if (is_array($jsonRet))
                        $res['msg'] = $jsonRet['msg'];
                    else
                        $res['msg'] = "电子合同接口返回数据错误";
                }
            }
        }

        return $res;
    }

    /**
     * 查询最近多少天的合同签订状态
     * 
     * @param datetime time_start 开始查询时间
     * @return array('rcode'=>'返回代码,1:成功；0：失败','data'=>'返回数据','msg'=>'提示消息')
    */
    public function batchRead( $time_start = false )
    {
        $res  = array('rcode'=>0,'msg'=>'参数错误', 'data'=>NULL);
        if (!$time_start) {
            $time_start = date('Y-m-d 0:0:0', strtotime("-3 day")); //默认查询最近三天的结果
        }

        $apiParam = array();
        $apiParam['time_start'] = $time_start;
        $apiParam['timestamp'] = date('YmdHis');
        $token = $this->_token();
        $ret = $this->_httpPost($this->m_api_base.self::API_BATCH_READ.'?token='.$token, $apiParam);
        $jsonRet = $ret&&json_decode($ret) ? json_decode($ret, true) : false;
        if (!$ret) {
            $res['msg'] = "接口访问失败";
        }
        else if ($ret&&$jsonRet['code']==self::ERR_POST_SUCCESS) {
            $res['msg'] = 'OK';
            $res['data'] = $jsonRet['data'];
            $res['rcode'] = 1;
        }
        else {
			$this->_clearTokenByCode( $jsonRet, $token);
            if (is_array($jsonRet))
                $res['msg'] = $jsonRet['msg'];
            else
                $res['msg'] = "电子合同接口返回数据错误";
        }

        return $res;
    }

    /**
     * 读取合同状态信息
     * 
    */
    public function surveyRead( $survey_code, $phone_number)
    {
        $res  = array('rcode'=>0,'msg'=>'参数错误', 'data'=>NULL);

        $apiParam = array();
        if ($survey_code)
            $apiParam['survey_code'] = $survey_code;
        if ($phone_number)
            $apiParam['phone_number'] = $phone_number;
        $token = $this->_token();
        $ret = $this->_httpPost($this->m_api_base.self::API_SURVEY_READ.'?token='.$token, $apiParam);
        $jsonRet = $ret&&json_decode($ret) ? json_decode($ret, true) : false;
        if (!$ret) {
            $res['msg'] = "接口访问失败";
        }
        else if ($ret&&$jsonRet['code']==self::ERR_POST_SUCCESS) {
            $res['msg'] = 'OK';
            $res['data'] = $jsonRet['data'];
            $res['rcode'] = 1;
        }
        else {
            $this->_clearTokenByCode( $jsonRet, $token);
            if (is_array($jsonRet))
                $res['msg'] = $jsonRet['msg'];
            else
                $res['msg'] = "电子合同接口返回数据错误";
        }

        return $res;
    }

    /**
     * 读取电子合同信息
     * @param  int $contract_id 合同ID 
     * @return array('rcode'=>'返回代码,1:成功；0：失败','data'=>'返回数据','msg'=>'提示消息')
     */
    public function read( $contract_id )
    {
        $res  = array('rcode'=>0,'msg'=>'参数错误', 'data'=>NULL);
        $MContract = D('Admin/Contract');
        $where = array();
        $where['contract_id'] = array('eq', $contract_id);

        $data = $MContract->where( $where )->find();
        if (!$data) {
            $res['msg'] = "合同数据不存在";
        }
        $apiParam = array();
        $apiParam['contract_number'] = $data['order_num'];
        $apiParam['timestamp'] = date('YmdHis');
        $token = $this->_token();
        $ret = $this->_httpPost($this->m_api_base.self::API_READ.'?token='.$token, $apiParam);
        $jsonRet = $ret&&json_decode($ret) ? json_decode($ret, true) : false;
        if (!$ret) {
            $res['msg'] = "接口访问失败";
        }
        else if ($ret&&$jsonRet['code']==self::ERR_POST_SUCCESS) {
            $res['msg'] = '';
            $data = array();
            $data['download_url'] = $jsonRet['download_url'];
            $data['viewpdf_url'] = $jsonRet['viewpdf_url'];
            $res['data'] = $data;
            $res['rcode'] = 1;
        }
        else {
            $this->_clearTokenByCode( $jsonRet, $token);
            if (is_array($jsonRet))
                $res['msg'] = $jsonRet['msg'];
            else
                $res['msg'] = "电子合同接口返回数据错误";
        }

        return $res;
    }

    /**
     * Token失效
    */
    private function _clearTokenByCode( $_code, $token){
        $code = '';
        if (is_array($_code)&&isset($_code['code'])&&$_code['code']){
            $code = $_code['code'];
        }
		if ( $code && in_array($code, array('3001','3002')) ) {
			$cacheData = F(self::CACHE_TOKEN_KEY);
			$tm = time();
			F(self::CACHE_TOKEN_KEY, NULL);
		}
    }

    /**
     * 根据配置文件中app_id, app_key 获取token数据
     * 
    */
    private function _token( $update = false )
    {
        $cacheToken = F(self::CACHE_TOKEN_KEY);
        $tm = time();
        if ($cacheToken&&isset($cacheToken['time']) && $cacheToken['time']>$tm && !$update){
            //主动刷新token缓存
            $cacheToken['time'] = $tm + self::TM_TOKEN_EXPIRE;
            F(self::CACHE_TOKEN_KEY, $cacheToken);
            return $cacheToken['token'];
        }
        if (!$cacheToken)
            $cacheToken = array();
        $config = C('ECONTRACT');
        $app_id = isset($config['APP_ID']) ? trim($config['APP_ID']):'';
        $app_key = isset($config['APP_KEY']) ? trim($config['APP_KEY']):'';
        $param = array();
        $param['app_id'] = $app_id;
        $param['app_secrect'] = $app_key;
        $ret = $this->_httpPost($this->m_api_base.self::API_TOKEN, $param);
        $jsonRet = $ret&&json_decode($ret) ? json_decode($ret, true) : false;
        if ($ret&&$jsonRet['code']==self::ERR_POST_SUCCESS){
            $cacheToken['time'] = time() + intval($jsonRet['expires']);
            $cacheToken['token'] = $jsonRet['data'];
            F(self::CACHE_TOKEN_KEY, $cacheToken);
            return $jsonRet['data'];
        }
        return '';
    }

    /**
     * 以get方式提交请求
     * @param $url
     * @return bool|mixed
     */
    private function _httpGet($url) {
        return  \Common\ORG\Tools\Http::get($url);
    }

    /**
     * 以post方式提交请求
     * @param string $url
     * @param array|string $postdata
     * @return bool|mixed
     */
    private function _httpPost($url, $data) {
        return  \Common\ORG\Tools\Http::post($url, $data);
    }
}